﻿/**
* @description  Class to tween individual properties of an object.
*/
package com.foed.animation {

	import flash.events.TimerEvent;
	import flash.utils.Timer;

	import com.foed.animation.easing.Linear;
	import com.foed.events.TweenEvent;

	public class Tweener extends Animator {
	
		private var _clip:Object;
		private var _prop:String;
		private var _startValue:Number;
		private var _destValue:Number;
		private var _changeValue:Number;
		private var _time:Number;
		private var _easeFunction:Function;
		private var _totalInts:uint;

		/**
		* @description  Constructor.
		*
		* @param  pClip  The object on which the tween will perform.
		* @param  pProp  The property of the object to tween.
		* @param  pStartValue  The value of the property at the start of the tween.
		* @param  pDestValue  The value of the property at the end of the tween.
		* @param  pTime  The number of milliseconds the tween should run.
		* @param  pEaseFunction  The function to use to calculate values during the tween.
		*/
		public function Tweener(
			pClip:Object,
			pProp:String,
			pStartValue:Number,
			pDestValue:Number,
			pTime:Number,
			pEaseFunction:Function=null
		) {
			_clip = pClip;
			_prop = pProp;
			_startValue = pStartValue;
			_destValue = pDestValue;
			_changeValue = _destValue - _startValue;
			_time = pTime;
			_totalInts = Math.floor(_time/Animator.intervalTime);
			_easeFunction = pEaseFunction||Linear.easeNone;
		}
	
		/**
		* @description  Called by the Timer to change the object's property over the course of the tween.
		*
		* @param  pEvent  The event fired by the Timer.
		*/
		private function runTween(pEvent:TimerEvent):void {
			_clip[_prop] = _easeFunction(_timer.currentCount, _startValue, _changeValue, _totalInts);
			if (_timer.currentCount >= _totalInts) {
				_clip[_prop] = _destValue;
				halt();
				dispatchEvent(new TweenEvent(TweenEvent.END, this));
			} else {
				dispatchEvent(new TweenEvent(TweenEvent.CHANGE, this));
			}
		}
	
		/**
		* @description  Starts the animation.
		*/
		override public function start():void {
			_clip[_prop] = _startValue;
			_timer = new Timer(Animator.intervalTime, _totalInts);
			_timer.addEventListener(TimerEvent.TIMER, runTween, false, 0, true);
			_timer.start();
			dispatchEvent(new TweenEvent(TweenEvent.START, this));
		}
	
		/**
		* @description  Stops the animation.
		*/
		override public function halt():void {
			_timer.removeEventListener(TimerEvent.TIMER, runTween);
			_timer.stop();
		}

		/**
		* @description  Cleans up any timers that might be running.
		*/
		override public function die():void {
			super.die();
			if (_timer && _timer.running) _timer.stop();
			_clip = null;
			_easeFunction = null;
		}

	}

}